
using System;
using System.Collections.Generic;
using System.Text;
using System.Net.Mail;

namespace ScrewTurn.Wiki.PluginFramework {

	/// <summary>
	/// It is the interface that the ScrewTurn Wiki's Host object implements.
	/// </summary>
	public interface IHost {

		/// <summary>
		/// Gets the values of the Wiki Settings.
		/// </summary>
		/// <param name="name">The Setting's Name.</param>
		/// <returns>The Setting's value.</returns>
		string GetSettingValue(SettingName name);

		/// <summary>
		/// Gets the list of the Users.
		/// </summary>
		UserInfo[] AllUsers { get; }

		/// <summary>
		/// Finds a user by username, properly handling Users Storage Providers.
		/// </summary>
		/// <param name="username">The username.</param>
		/// <returns>The <see cref="T:UserInfo" />, or <b>null</b> if no users are found.</returns>
		UserInfo FindUser(string username);

		/// <summary>
		/// Gets the list of the Pages.
		/// </summary>
		PageInfo[] AllPages { get; }

		/// <summary>
		/// Gets the list of the Categories.
		/// </summary>
		CategoryInfo[] AllCategories { get; }

		/// <summary>
		/// Gets the list of Snippets.
		/// </summary>
		Snippet[] AllSnippets { get; }

		/// <summary>
		/// Gets the list of Navigation Paths.
		/// </summary>
		NavigationPath[] AllNavigationPaths { get; }

		/// <summary>
		/// Gets the Categories of a Page.
		/// </summary>
		/// <param name="page">The Page.</param>
		/// <returns>The Categories.</returns>
		CategoryInfo[] GetCategoriesPerPage(PageInfo page);

		/// <summary>
		/// Gets the WikiPage with the specified Name, or null.
		/// </summary>
		/// <param name="name">The Name of the Page.</param>
		/// <returns>The Wiki Page, or null.</returns>
		PageInfo FindPage(string name);

		/// <summary>
		/// Gets the Content of a Page.
		/// </summary>
		/// <param name="page">The Page.</param>
		/// <returns>The Page Content.</returns>
		PageContent GetPageContent(PageInfo page);

		/// <summary>
		/// Gets the Backup/Revision numbers of a Page.
		/// </summary>
		/// <param name="page">The Page.</param>
		/// <returns>The Backup/Revision numbers.</returns>
		int[] GetBackups(PageInfo page);

		/// <summary>
		/// Gets the Content of a Page Backup.
		/// </summary>
		/// <param name="page">The Page.</param>
		/// <param name="revision">The revision.</param>
		/// <returns>The Backup Content.</returns>
		PageContent GetBackupContent(PageInfo page, int revision);

		/// <summary>
		/// Gets the formatted content of a Page, retrieving it from the cache (if available).
		/// </summary>
		/// <param name="page">The Page.</param>
		/// <returns>The formatted content of the Page.</returns>
		string GetFormattedContent(PageInfo page);

		/// <summary>
		/// Formats a block of WikiMarkup, using the built-in formatter only.
		/// </summary>
		/// <param name="raw">The block of WikiMarkup.</param>
		/// <returns>The formatted content.</returns>
		string Format(string raw);

		/// <summary>
		/// Sends an Email.
		/// </summary>
		/// <param name="recipient">The Recipient Email address.</param>
		/// <param name="sender">The Sender's Email address.</param>
		/// <param name="subject">The Subject.</param>
		/// <param name="body">The Body.</param>
		/// <param name="html">True if the message is HTML.</param>
		/// <returns>True if the message has been sent successfully.</returns>
		bool SendEmail(string recipient, string sender, string subject, string body, bool html);

		/// <summary>
		/// Logs a new message.
		/// </summary>
		/// <param name="message">The Message.</param>
		/// <param name="entryType">The Entry Type.</param>
		/// <param name="caller">The Component that calls the method. The caller cannot be null.</param>
		void LogEntry(string message, LogEntryType entryType, object caller);

		/// <summary>
		/// Reads a text file.
		/// </summary>
		/// <param name="filename">The filename.</param>
		/// <returns>The content of the file.</returns>
		string ReadFile(string filename);

		/// <summary>
		/// Writes a text file.
		/// </summary>
		/// <param name="filename">The filename.</param>
		/// <param name="content">The content.</param>
		/// <returns>True if the file is written.</returns>
		bool WriteFile(string filename, string content);

		/// <summary>
		/// Aligns a Date and Time object to the User's Time Zone preferences.
		/// </summary>
		/// <param name="dt">The Date/Time to align.</param>
		/// <returns>The aligned Date/Time.</returns>
		/// <remarks>The method takes care of daylight saving settings.</remarks>
		DateTime AlignDateTimeWithPreferences(DateTime dt);

		/// <summary>
		/// Forces to reload a list of items.
		/// </summary>
		/// <param name="list">The list to Reload.</param>
		/// <param name="caller">The Component that calls the method. The caller cannot be null.</param>
		void RequestRefresh(RefreshList list, object caller);

		/// <summary>
		/// Clears the cache.
		/// </summary>
		/// <param name="data">The part of the cache to clear.</param>
		void ClearCache(CacheData data);

		/// <summary>
		/// Adds an item in the Editing Toolbar.
		/// </summary>
		/// <param name="item">The item to add.</param>
		/// <param name="text">The text of the item.</param>
		/// <param name="value">The value of the item: if <b>item</b> is <b>ToolbarItem.SpecialTagWrap</b>, separate start and end tag with a pipe.</param>
		void AddToolbarItem(ToolbarItem item, string text, string value);

		/// <summary>
		/// Event fired whenever an activity is performed on a User Account.
		/// </summary>
		event EventHandler<UserAccountActivityEventArgs> UserAccountActivity;

		/// <summary>
		/// Even fired whenever an activity is performed on a Page.
		/// </summary>
		event EventHandler<PageActivityEventArgs> PageActivity;

	}

	/// <summary>
	/// Contains arguments for User Account Activity events.
	/// </summary>
	public class UserAccountActivityEventArgs : EventArgs {

		private UserInfo user;
		private UserAccountActivity activity;

		/// <summary>
		/// Initializes a new instance of the <b>UserAccountActivityEventArgs</b> class.
		/// </summary>
		/// <param name="user">The User Info the activity refers to.</param>
		/// <param name="activity">The activity performed.</param>
		public UserAccountActivityEventArgs(UserInfo user, UserAccountActivity activity) {
			this.user = user;
			this.activity = activity;
		}

		/// <summary>
		/// Gets the user the activity refers to.
		/// </summary>
		public UserInfo User {
			get { return user; }
		}

		/// <summary>
		/// Gets the activity performed.
		/// </summary>
		public UserAccountActivity Activity {
			get { return activity; }
		}

	}

	/// <summary>
	/// Lists legal User Account Activity types.
	/// </summary>
	public enum UserAccountActivity {
		/// <summary>
		/// A user account has been added.
		/// </summary>
		AccountAdded,
		/// <summary>
		/// A user account has been activated.
		/// </summary>
		AccountActivated,
		/// <summary>
		/// A user account has been deactivated.
		/// </summary>
		AccountDeactivated,
		/// <summary>
		/// A user account has been promoted to administrator.
		/// </summary>
		AccountPromoted,
		/// <summary>
		/// A user account has been downgraded to normal user.
		/// </summary>
		AccountDowngraded,
		/// <summary>
		/// A user account has been modified (email, password).
		/// </summary>
		AccountModified,
		/// <summary>
		/// A user account has been removed.
		/// </summary>
		AccountRemoved
	}

	/// <summary>
	/// Contains arguments for Page Activity events.
	/// </summary>
	public class PageActivityEventArgs : EventArgs {

		private PageInfo page;
		private string author;
		private PageActivity activity;

		/// <summary>
		/// Initializes a new instance of the <b>PageActivityEventArgs</b> class.
		/// </summary>
		/// <param name="page">The page the activity refers to.</param>
		/// <param name="author">The author of the activity, if available, <b>null</b> otherwise.</param>
		/// <param name="activity">The activity.</param>
		public PageActivityEventArgs(PageInfo page, string author, PageActivity activity) {
			this.page = page;
			this.author = author;
			this.activity = activity;
		}

		/// <summary>
		/// Gets the page the activity refers to.
		/// </summary>
		public PageInfo Page {
			get { return page; }
		}

		/// <summary>
		/// Gets the author of the activity.
		/// </summary>
		public string Author {
			get { return author; }
		}

		/// <summary>
		/// Gets the activity.
		/// </summary>
		public PageActivity Activity {
			get { return activity; }
		}

	}

	/// <summary>
	/// Lists legal Page Activity types.
	/// </summary>
	public enum PageActivity {
		/// <summary>
		/// A page has been created.
		/// </summary>
		PageCreated,
		/// <summary>
		/// A page has been modified.
		/// </summary>
		PageModified,
		/// <summary>
		/// A page has been renamed.
		/// </summary>
		PageRenamed,
		/// <summary>
		/// A page has been rolled back.
		/// </summary>
		PageRolledBack,
		/// <summary>
		/// A page's backups have been deleted.
		/// </summary>
		PageBackupsDeleted,
		/// <summary>
		/// A page's status has been changed.
		/// </summary>
		PageStatusChanged,
		/// <summary>
		/// A page has been deleted.
		/// </summary>
		PageDeleted,
		/// <summary>
		/// A message has been posted to a page discussion.
		/// </summary>
		MessagePosted,
		/// <summary>
		/// A message has been modified.
		/// </summary>
		MessageModified,
		/// <summary>
		/// A message has been deleted from a page discussion.
		/// </summary>
		MessageDeleted
	}

	/// <summary>
	/// Enumerates the Types of Log Entries.
	/// </summary>
	public enum LogEntryType {
		/// <summary>
		/// Represents a simple Message.
		/// </summary>
		General,
		/// <summary>
		/// Represents a Warning.
		/// </summary>
		Warning,
		/// <summary>
		/// Represents an Error.
		/// </summary>
		Error
	}

	/// <summary>
	/// Enumerates the Setting values' names.
	/// </summary>
	public enum SettingName {
		/// <summary>
		/// The Title of the Wiki.
		/// </summary>
		WikiTitle,
		/// <summary>
		/// The Main URL of the Wiki.
		/// </summary>
		MainUrl,
		/// <summary>
		/// The current Theme Name.
		/// </summary>
		Theme,
		/// <summary>
		/// The Contact Email.
		/// </summary>
		ContactEmail,
		/// <summary>
		/// The Sender Email.
		/// </summary>
		SenderEmail,
		/// <summary>
		/// The current Theme relative path (URL).
		/// </summary>
		ThemePath,
		/// <summary>
		/// The Name of the default Page.
		/// </summary>
		DefaultPage,
		/// <summary>
		/// The Date/Time format.
		/// </summary>
		DateTimeFormat,
		/// <summary>
		/// The default Language (for example <b>en-US</b>).
		/// </summary>
		DefaultLanguage,
		/// <summary>
		/// The default Time Zone (a string representing the shift in <b>minutes</b> respect to the Greenwich time, for example <b>-120</b>).
		/// </summary>
		DefaultTimeZone,
		/// <summary>
		/// The Wiki Access status (<b>PRIVATE</b>, <b>NORMAL</b>, <b>PUBLIC</b>).
		/// </summary>
		AccessStatus,
		/// <summary>
		/// The Themes directory.
		/// </summary>
		ThemesDirectory,
		/// <summary>
		/// The Public directory.
		/// </summary>
		PublicDirectory,
		/// <summary>
		/// The Messages directory.
		/// </summary>
		MessagesDirectory,
		/// <summary>
		/// The Pages directory.
		/// </summary>
		PagesDirectory,
		/// <summary>
		/// The Plugins directory.
		/// </summary>
		PluginsDirectory,
		/// <summary>
		/// The Snippets directory.
		/// </summary>
		SnippetsDirectory,
		/// <summary>
		/// The Temp directory.
		/// </summary>
		TempDirectory,
		/// <summary>
		/// The Upload directory.
		/// </summary>
		UploadDirectory,
		/// <summary>
		/// A value (true/false) indicating whether users can create new pages.
		/// </summary>
		UsersCanCreateNewPages,
		/// <summary>
		/// A value (true/false) indicating whether users can create new categories.
		/// </summary>
		UsersCanCreateNewCategories,
		/// <summary>
		/// A value (true/false) indicating whether users can create delete files.
		/// </summary>
		UsersCanDeleteFiles,
		/// <summary>
		/// A value (true/false) indicating whether users can manage page categories.
		/// </summary>
		UsersCanManageCategories,
		/// <summary>
		/// A value (true/false) indicating whether users can create new accounts.
		/// </summary>
		UsersCanRegister,
		/// <summary>
		/// A value (true/false) indicating whether users can upload files.
		/// </summary>
		UsersCanUploadFiles,
		/// <summary>
		/// A value (true/false) indicating whether users can view uploaded files.
		/// </summary>
		UsersCanViewFiles,
		/// <summary>
		/// The regex used to validate usernames.
		/// </summary>
		UsernameRegex,
		/// <summary>
		/// The regex used to validate passwords.
		/// </summary>
		PasswordRegex,
		/// <summary>
		/// The regex used to validate email addresses.
		/// </summary>
		EmailRegex,
		/// <summary>
		/// The regex used to validate the main Wiki URL.
		/// </summary>
		MainUrlRegex,
		/// <summary>
		/// A value (true/false) indicating whether to activate page editing with a double click.
		/// </summary>
		EnableDoubleClickEditing,
		/// <summary>
		/// A value (true/false) indicating whether to process single line breaks in WikiMarkup.
		/// </summary>
		ProcessSingleLineBreaks,
		/// <summary>
		/// The account activation mode.
		/// </summary>
		AccountActivationMode,
		/// <summary>
		/// The file types allowed for upload.
		/// </summary>
		AllowedFileTypes,
		/// <summary>
		/// A value (true/false) indicating whether the configuration tab is visible to administrators other than the built-in 'admin'.
		/// </summary>
		ConfigVisibleToAdmins,
		/// <summary>
		/// A value (true/false) indicating whether to disable the automatic version check.
		/// </summary>
		DisableAutomaticVersionCheck,
		/// <summary>
		/// A value (true/false) indicating whether to disable the breadcrumbs trail.
		/// </summary>
		DisableBreadcrumbsTrail,
		/// <summary>
		/// A value (true/false) indicating whether to disable the page cache.
		/// </summary>
		DisableCache,
		/// <summary>
		/// A value (true/false) indicating whether to disable the captcha control in public functionalities.
		/// </summary>
		DisableCaptchaControl,
		/// <summary>
		/// A value (true/false) indicating whether to disable concurrent page editing.
		/// </summary>
		DisableConcurrentEditing,
		/// <summary>
		/// The page discussion permissions.
		/// </summary>
		DiscussionPermissions,
		/// <summary>
		/// A value (true/false) indicating whether to enable HTTP compression.
		/// </summary>
		EnableHttpCompression,
		/// <summary>
		/// A value (true/false) indicating whether to enable View State compression.
		/// </summary>
		EnableViewStateCompression,
		/// <summary>
		/// The number of file access tries.
		/// </summary>
		FileAccessTries,
		/// <summary>
		/// The delay between failed file access tries (milliseconds).
		/// </summary>
		FileAccessTryDelay,
		/// <summary>
		/// A value (true/false) indicating whether to file management is allowed to anonymous users when the Wiki is in Public Access mode.
		/// </summary>
		FileManagementInPublicAccessAllowed,
		/// <summary>
		/// The logging level.
		/// </summary>
		LoggingLevel,
		/// <summary>
		/// The max size for uploaded files (bytes).
		/// </summary>
		MaxFileSize,
		/// <summary>
		/// The extension used for pages.
		/// </summary>
		PageExtension,
		/// <summary>
		/// A value (true/false) indicating whether to SCRIPT tags are allowed in WikiMarkup.
		/// </summary>
		ScriptTagsAllowed,
		/// <summary>
		/// The version of the Wiki Engine.
		/// </summary>
		WikiVersion,
	}

	/// <summary>
	/// Enumerates the refreshable Lists.
	/// </summary>
	public enum RefreshList {
		/// <summary>
		/// The Users list.
		/// </summary>
		Users,
		/// <summary>
		/// The Pages list.
		/// </summary>
		Pages
	}

	/// <summary>
	/// Enumerates the parts of the cache that can be cleared.
	/// </summary>
	public enum CacheData {
		/// <summary>
		/// All the pages data.
		/// </summary>
		Pages,
		/// <summary>
		/// All the meta-files (Header, Footer, Sidebar, etc.).
		/// </summary>
		MetaFiles
	}

	/// <summary>
	/// Enumerates the toolbar items that can be added.
	/// </summary>
	[Serializable]
	public enum ToolbarItem {
		/// <summary>
		/// A Special Tag that is inserted in the text.
		/// </summary>
		SpecialTag,
		/// <summary>
		/// A special tag that wraps the selected text.
		/// </summary>
		SpecialTagWrap
	}

}
